<?php


class SpeciesTable extends Doctrine_Table
{
    
    public static function getInstance()
    {
        return Doctrine_Core::getTable('Species');
    }

    /**
     * Extend from function findByDql but with limit parameter
     * @param string                    $dql Dql where clause
     * @param array $params             statement parameters
     * @param int $limit                limit
     * @param <type> $hydrationMode     @see 
     * @return Doctrine_Collection or Array
     */
    public function findWithLimit($dql, $params = array(), $limit = 10, $hydrationMode = null) {
        return $this->createQuery('sp')
                ->where($dql, $params)
                ->limit($limit)
                ->execute();
    }

//    public function findSimilars($search) {
//
//        sfContext::getInstance()->getLogger()->debug('find similar..');
//
//        // init paging reader
//        $pager = new sfDoctrinePager('Species', 50);
//        $pager->setQuery($this->createQuery('sp')->select('species'));
//
//        // stack of n-top species that similars to searched item.
//        // levenshtein value as the key and the species as the value.
//        $stack = array();
//        $size = 10;
//        $page = 1;
//
//        do {
//            $pager->setPage($page);
//            $pager->init();
//
//            $result = $pager->getResults();
//
//            sfContext::getInstance()->getLogger()->debug('page: ' . $pager->getPage());
//            sfContext::getInstance()->getLogger()->debug('count result: ' . $result->count());
//
//            // read by paging
//            foreach($result as $species) {
//
//                // calculate the distance between input and the current species
//                $sim = $this->lcs_len($search, $species['species']);
//
//                if ($sim == 0) {
//
//                } else {
//
//                    $count = count($stack);
//
//                    // if stack size less then size, then insert directly
//                    if ($count < $size) {
//                        $stack[$count] = array('distance' => $sim, 'species' => $species['species']);
//
//                        sfContext::getInstance()->getLogger()->debug('insert -> ' . $stack[$count]['distance'] . ', ' . $stack[$count]['species']);
//                    }
//
//                    // else, compare per item to replace the smallest distance
//                    else {
//                        $smallestSim = 10000; $pos;
//                        for ($i = 0; $i < count($stack); $i++) {
//                            if ($stack[$i]['distance'] < $smallestSim) {
//                                $smallestSim = $stack[$i]['distance'];
//                                $pos = $i;
//                            }
//                        }
//
//                        // only replace if the smallest is less than current distance
//                        if ($smallestSim < $sim) {
//                            sfContext::getInstance()->getLogger()->debug('smallest: ' . $stack[$pos]['distance'] . ', ' . $stack[$pos]['species']);
//
//                            $stack[$pos] = array('distance' => $sim, 'species' => $species['species']);
//
//                            sfContext::getInstance()->getLogger()->debug('insert -> species: ' . $stack[$pos]['distance'] . ', ' . $stack[$pos]['species']);
//                        }
//                    }
//                }
//            }
//
//            $page = $pager->getNextPage();
//
//        } while(!$pager->isLastPage());
//
//        return $stack;
//    }

    public function lcs_len ($str1, $str2) {

//        sfContext::getInstance()->getLogger()->debug('lcs: ' . $str1 . ', ' . $str2);

        if (empty($str1) || empty($str2)) {
//            sfContext::getInstance()->getLogger()->debug('lcs: 0');
            return 0;
        }

        $substr1 = substr($str1, 0, strlen($str1)-2);
        $substr2 = substr($str2, 0, strlen($str2)-2);

        if ($str1[strlen($str1)-1] == $str2[strlen($str2)-1]) {
//            sfContext::getInstance()->getLogger()->debug('lcs: +1');
            return $this->lcs_len($substr1, $substr2) + 1;
        } else {
            return max($this->lcs_len($str1, $substr2), $this->lcs_len($str2, $substr1));
        }
    }

    /**
     * Find a record by fieldvalues, or if not found return new Species object
     * @param array $params array of $params[fieldname] = fieldvalue
     * @return Species object
     */
    public function findOrCreate(array $params = array())
    {
        $record;
        if (isset($params['id']))
            $record = $this->findOneBy('id', $params['id']);
        
        if (empty($record) && isset($params['species']))
            $record = $this->findOneBy('species', $params['species']);

        if (empty($record))
        {
            $record = $this->create($params);
            $record->save();
        }

        return $record;
    }

    /**
     * Insert a species only if not exists in database
     * @param array $params     $params[fieldname] = fieldvalue
     * @return Doctrine_Record of Species
     */
    public function insertIfNotExist($params = array()) {
        sfContext::getInstance()->getLogger()->debug('insertIfNotExist');

        if (!isset($params['species'])) {
            sfContext::getInstance()->getLogger()->debug('empty species name');
            return false;
        }

        $record = $this->findOneBy('species', $params['species']);

        if ($record) {
            // if record found, return false
            sfContext::getInstance()->getLogger()->debug('species ' . $record->getSpecies() . ' already exists.');
            return false;
        } else {
            // else create new species
            sfContext::getInstance()->getLogger()->debug('create new species ' . $params['species']);
            $record = $this->create($params);
            $record->save();
            return $record;
        }
    }
}